﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using QuadRemote.Core;

namespace QuadRemote.Tabs
{
    public partial class ESCControl : UserControl
    {
        private delegate void cmdOutDelegate(CommandOut args);
        private delegate void cmdInDelegate(CommandIn args);

        int selectedMotor = -1;
        HEXReader firmware;
        DateTime firmwareLastModified;
        CommandOut setRPMCmd;

        public ESCControl()
        {
            InitializeComponent();

            Timer bootloaderRefreshTimer = new Timer();
            bootloaderRefreshTimer.Interval = 500;
            bootloaderRefreshTimer.Tick += bootloaderRefreshTimer_Tick;
            bootloaderRefreshTimer.Start();

            disableAll();
        }

        void bootloaderRefreshTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                DateTime t = System.IO.File.GetLastWriteTime(Properties.Settings.Default.ESCFirmware);
                if (t > firmwareLastModified)
                {
                    loadFirmware(Properties.Settings.Default.ESCFirmware);
                    firmwareLastModified = t;
                }
            }
            catch (Exception ee)
            {
                firmware = null;
            }
        }


        private void incomingAddressesPacket(CommandOut args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(incomingAddressesPacket), new object[] { args });
                return;
            }
            if (!args.eventResponse)
            {
                cbESC.Items.Clear();
                cbESC.Items.Add("Error scanning bus");
                cbESC.SelectedIndex = 0;
                selectedMotor = -1;
                disableAll();
                return;
            }
            cbESC.Enabled = true;
            int selected = selectedMotor;
            cbESC.Items.Clear();
            int i;
            for (i = 0; i < args.responsePacket.packet.Length; i ++)
            {
                byte addr = args.responsePacket.packet[i];
                cbESC.Items.Add("ESC " + (i + 1) + " @ 0x" + Tools.getHexString(addr));
            }

            if (selected > -1 && cbESC.Items.Count > selected)
                cbESC.SelectedIndex = selected;
        }

        private void bootloaderSet(CommandOut args)
        {
            if (args.eventResponse)
                new CommandOut(CommandId.CMD_ESC_INFO, args.responsePacket.packet[0]).callbackOnResponsePacket(CommandId.CMD_ESC_INFO, receivedInfoPacket).send();
        }

        private void receivedInfoPacket(CommandOut args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(receivedInfoPacket), new object[] { args });
                return;
            }
            if (!args.eventResponse || args.responsePacket.packet.Length < 8)
            {
                lblBootloader.Text = "0x: Error";
            }
            else
            {
                btBootloader.Text = args.responsePacket.packet[2] == 1 ? "Exit boot" : "Enter boot";
                lblBootloader.Text = "0x" + Tools.getHexString(args.responsePacket.packet[1]) + ": V" + (int)args.responsePacket.packet[3] + "." + (int)args.responsePacket.packet[4] + " dev " + Tools.getHexString(args.responsePacket.packet, 5, 4);
                enableAll(args.responsePacket.packet[2] == 1);
            }
        }

        private void incomingFlashWordPacket(CommandOut args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(incomingFlashWordPacket), new object[] { args });
                return;
            }
        }


        private void incomingSettingsPacket(CommandOut args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(incomingSettingsPacket), new object[] { args });
                return;
            }

            lstSettings.Items.Clear();

            if (args.eventTimeout)
            {
                lstSettings.Items.Add("Error");
                return;
            }

            int i;
            for (i = 2; i < args.responsePacket.packet.Length; i++)
            {
                byte id = args.responsePacket.packet[i];
                if (id == 0xFF) break;
                i++;
                String name = Tools.bytesToString(args.responsePacket.packet, i);
                i += name.Length + 1;

                int val = (args.responsePacket.packet[i] << 8) | (args.responsePacket.packet[i + 1]);
                i ++;
                lstSettings.Items.Add((int)id + ": " + name + " (" + (val == 65535 ? "unset" : ""+val) + ")");
            }
        }

        private void btSelectFirmware_Click(object sender, EventArgs e)
        {
            OpenFileDialog file = new OpenFileDialog();
            file.Filter = "PIC Hex (*.hex)|*.hex";
            file.InitialDirectory = Properties.Settings.Default.ESCFirmware;
            file.ShowDialog();
            if (file.FileName == "") return;

            loadFirmware(file.FileName);
        }

        private void loadFirmware(String filename)
        {
            try
            {
                firmware = new HEXReader(filename, HEXReader.FORMAT_PIC33);
                String part = filename.Substring(filename.LastIndexOf("\\")+1);

                byte[] version = firmware.getBytesAt(2048, 2);

                lblSelectedFirmware.Text = "V" + (int)version[1] + "." + (int)version[0] + " (" + firmware.getTotalBytes() + " bytes)";
                Properties.Settings.Default.ESCFirmware = filename;
                Properties.Settings.Default.Save();
            }
            catch (Exception e)
            {
                lblSelectedFirmware.Text = "Error";
                firmware = null;
            }
        }

        private void btGetSettings_Click(object sender, EventArgs e)
        {
            if (selectedMotor == -1) return;

            new CommandOut(CommandId.CMD_ESC_SETTINGS, (byte)selectedMotor)
                .callbackOnResponsePacket(CommandId.CMD_ESC_SETTINGS, incomingSettingsPacket)
                .send();
        }

        private void btSettingsWrite_Click(object sender, EventArgs e)
        {
            if (selectedMotor == -1) return;

            new CommandOut(CommandId.CMD_ESC_SETTINGS_WRITE, (byte)selectedMotor)
                .send();
        }

        private void btBootloader_Click(object sender, EventArgs e)
        {
            if (selectedMotor == -1) return;

            if (btBootloader.Text.Substring(0,5) == "Enter")
            {
                new CommandOut(CommandId.CMD_ESC_BOOTLOADER, (byte)selectedMotor, 1)
                    .callbackOnResponsePacket(CommandId.CMD_ESC_BOOTLOADER, bootloaderSet)
                    .send();
            }
            else
            {
                new CommandOut(CommandId.CMD_ESC_BOOTLOADER, (byte)selectedMotor, 0)
                    .callbackOnResponsePacket(CommandId.CMD_ESC_BOOTLOADER, bootloaderSet)
                    .send();

            }
        }

        bool firmwareWriting = false;
        int firmwareESCId;
        int firmwareWritingPage;
        int firmwareWritingRow;
        int firmwareWrittenBytes;

        private void btWriteSelected_Click(object sender, EventArgs e)
        {
            if (selectedMotor == -1) return;
            if (firmware == null) return;

            firmwareWriting = true;
            firmwareESCId = selectedMotor;
            startFirmwareWriting();
        }

        private void firmwareWritingBootloaderResult(CommandOut cmd)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(firmwareWritingBootloaderResult), new object[] { cmd });
                return;
            }

            if (!cmd.eventResponse || cmd.responsePacket.packet[1] != 1)
            {
                firmwareWriting = false;
                lblFirmwareProgress.Text = "Progress: aborted, not in bootloader";
                pbFirmware.Value = pbFirmware.Maximum;
                return;
            }

            firmwareWriteNextRow();
        }

        private void startFirmwareWriting()
        {
            pbFirmware.Value = 0;
            lblFirmwareProgress.Text = "Progress: checking bootloader...";
            firmwareWritingPage = 0;
            firmwareWritingRow = 0;
            firmwareWrittenBytes = 0;

            //new CommandOut(CommandId.CMD_MOTOR_SET_BOOTLOADER, (byte)firmwareESCId, 1)
            //    .callbackOnResponsePacket(CommandId.CMD_MOTOR_SET_BOOTLOADER, firmwareWritingBootloaderResult)
            //    .send();
            new CommandOut(CommandId.CMD_ESC_BOOTLOADER, (byte)firmwareESCId, 1)
                .callbackOnResponsePacket(CommandId.CMD_ESC_BOOTLOADER, firmwareWritingBootloaderResult)
                .send();
        }

        private void firmwareWriteNextRow()
        {
            lblFirmwareProgress.Text = "Progress: writing bytes " + firmwareWrittenBytes + " / " + firmware.getTotalBytes();

            HEXBlock block = firmware.getBlock(firmwareWritingPage);

            int address = block.address + block.addressPerRow * firmwareWritingRow;
            pbFirmware.Value = firmwareWrittenBytes;
            pbFirmware.Maximum = firmware.getTotalBytes();

            byte[] packet = new byte[block.rows[firmwareWritingRow].Length + 3 + 1];
            packet[0] = (byte)firmwareESCId;
            packet[1] = (byte)(address);
            packet[2] = (byte)(address >> 8);
            packet[3] = (byte)(address >> 16);
            Array.Copy(block.rows[firmwareWritingRow], 0, packet, 4, block.rows[firmwareWritingRow].Length);

            new CommandOut(CommandId.CMD_ESC_FIRMWARE_FLASH_ROW, packet)
                .callbackOnResponsePacket(CommandId.CMD_ESC_FIRMWARE_FLASH_ROW, incomingFlashRowPacket)
                .send();
        }

        private void incomingFlashRowPacket(CommandOut args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(incomingFlashRowPacket), new object[] { args });
                return;
            }
            if (args.eventTimeout)
            {
                Console.WriteLine("Flash timedout!");
                return;
            }

            Console.WriteLine("Flash response: " + Tools.getHexString(args.responsePacket.packet));

            if (args.responsePacket.packet[1] == 1)
            {
                HEXBlock block = firmware.getBlock(firmwareWritingPage);
                firmwareWrittenBytes += block.rows[firmwareWritingRow].Length;

                firmwareWritingRow++;
                if (firmwareWritingRow == block.rows.Length)
                {
                    firmwareWritingPage++;
                    firmwareWritingRow = 0;

                    block = firmware.getBlock(firmwareWritingPage);
                    if (block == null)
                    {
                        firmwareWriting = false;
                        lblFirmwareProgress.Text = "Progress: done";
                        pbFirmware.Value = pbFirmware.Maximum;

                        new CommandOut(CommandId.CMD_ESC_INFO, (byte)firmwareESCId)
                            .callbackOnResponsePacket(CommandId.CMD_ESC_INFO, receivedInfoPacket)
                            .send();
                    }
                    else
                        firmwareWriteNextRow();
                }
                else
                    firmwareWriteNextRow();
            }
            else
            {
                firmwareWriting = false;
                pbFirmware.Value = pbFirmware.Maximum;
                lblFirmwareProgress.Text = "Progress: aborted, error while writing";
            }
        }

        private void tbRPM_Scroll(object sender, EventArgs e)
        {
            if (chManualRPM.Checked && selectedMotor > -1)
            {
                int val = tbRPM.Value;

                if (setRPMCmd != null && setRPMCmd.timeSentAt == 0)
                {
                    setRPMCmd.body[2] = (byte)(val >> 8);
                    setRPMCmd.body[3] = (byte)val;
                }
                else
                {
                    setRPMCmd = new CommandOut(CommandId.CMD_ESC_SET_DEBUG_RPM, (byte)selectedMotor, (byte)(val >> 8), (byte)val);
                    setRPMCmd.send();
                }
            }
        }

        private void feedbackResponse(CommandOut cmd)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(feedbackResponse), new object[] { cmd });
                return;
            }

            if (!cmd.eventResponse) return;

            byte logId = cmd.responsePacket.packet[1];
            while (graphFrame.plots.Count > 0)
                graphFrame.removePlot(graphFrame.plots[0].container, graphFrame.plots[0].containerValue);

            if (FlightSession.current().Log.values.ContainsKey(logId))
            {
                LogValueContainer container = FlightSession.current().Log.values[logId];
                for (int i = 0; i < container.numValues; i++)
                    graphFrame.addPlot(container, i);
            }
        }

        private void disableAll()
        {
            btGetSettings.Enabled = false;
            btSettingsSet.Enabled = false;
            btSettingsWrite.Enabled = false;
            btBodeStart.Enabled = false;
            btBodeSetRPM.Enabled = false;
            btBodeCancel.Enabled = false;
            btBootloader.Enabled = false;
            btWriteSelected.Enabled = false;
            chManualRPM.Enabled = false;
        }

        private void enableAll(Boolean bootloaderActive)
        {
            btGetSettings.Enabled = !bootloaderActive;
            btSettingsSet.Enabled = !bootloaderActive;
            btSettingsWrite.Enabled = !bootloaderActive;
            btBodeStart.Enabled = !bootloaderActive;
            btBodeSetRPM.Enabled = !bootloaderActive;
            btBodeCancel.Enabled = !bootloaderActive;
            btBootloader.Enabled = true;
            btWriteSelected.Enabled = bootloaderActive;
            chManualRPM.Enabled = !bootloaderActive;
        }

        private void cbESC_SelectedIndexChanged(object sender, EventArgs e)
        {
            disableAll();
            if (cbESC.SelectedIndex == -1) return;
            if (((String)cbESC.SelectedItem).Substring(0, 3) != "ESC") return;

            selectedMotor = cbESC.SelectedIndex;
            new CommandOut(CommandId.CMD_ESC_INFO, (byte)selectedMotor)
                .callbackOnResponsePacket(CommandId.CMD_ESC_INFO, receivedInfoPacket)
                .send();
        }

        private void btScanBus_Click(object sender, EventArgs e)
        {
            cbESC.Enabled = false;

            new CommandOut(CommandId.CMD_ESC_ADDRESSES).callbackOnResponsePacket(CommandId.CMD_ESC_ADDRESSES, incomingAddressesPacket).send();
        }

        private void btSettingsSet_Click(object sender, EventArgs e)
        {
            if (selectedMotor == -1) return;
            if (lstSettings.SelectedIndex == -1) return;

            String val = (String)lstSettings.SelectedItem;
            if (val.IndexOf(":") < 0) return;
            val = val.Substring(0, val.IndexOf(":"));
            int valId = Int32.Parse(val);
            int value = Int32.Parse(txtSettingsValue.Text);

            new CommandOut(CommandId.CMD_ESC_SETTING_SET, (byte)selectedMotor, (byte)valId, (byte)(value >> 8), (byte)(value & 0xFF))
                .send();
        }

        private void chManualRPM_CheckedChanged(object sender, EventArgs e)
        {
            if (selectedMotor == -1) return;

            if (chManualRPM.Checked)
                tbRPM_Scroll(null, null);
            else
                new CommandOut(CommandId.CMD_ESC_SET_DEBUG_RPM).send();
        }

        private void incomingBodePacketa(CommandIn cmd)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdInDelegate(incomingBodePacketa), new object[] { cmd });
                return;
            }

            Console.WriteLine("Bode incoming for " + cmd.packet[0]);
            int freq = Tools.bytesToShort(cmd.packet,1);

            /*float Re_error = Tools.bytesToFloat(cmd.packet, 3);
            float Im_error = Tools.bytesToFloat(cmd.packet, 7);
            float Re_out = Tools.bytesToFloat(cmd.packet, 11);
            float Im_out = Tools.bytesToFloat(cmd.packet, 15);
            float Re_in = Tools.bytesToFloat(cmd.packet, 19);
            float Im_in = Tools.bytesToFloat(cmd.packet, 23);
            float Re_signal = Tools.bytesToFloat(cmd.packet, 27);
            float Im_signal = Tools.bytesToFloat(cmd.packet, 31);*/

            float Re_error = Tools.bytesToRealFloat(cmd.packet, 3);
            float Im_error = Tools.bytesToRealFloat(cmd.packet, 7);
            float Re_out = Tools.bytesToRealFloat(cmd.packet, 11);
            float Im_out = Tools.bytesToRealFloat(cmd.packet, 15);
            float Re_in = Tools.bytesToRealFloat(cmd.packet, 19);
            float Im_in = Tools.bytesToRealFloat(cmd.packet, 23);
            float Re_signal = Tools.bytesToRealFloat(cmd.packet, 27);
            float Im_signal = Tools.bytesToRealFloat(cmd.packet, 31);
            Console.WriteLine((float)(freq / 10.0) + "\t" +
                                Re_error + "\t" +
                                Im_error + "\t" +
                                Re_out + "\t" +
                                Im_out + "\t" +
                                Re_in + "\t" +
                                Im_in + "\t" +
                                Re_signal + "\t" +
                                Im_signal);
        }

        private void groupBox3_Enter(object sender, EventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void tbRPM_Scroll_1(object sender, EventArgs e)
        {

        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            tbRPM.Minimum = chAllowReverse.Checked ? -tbRPM.Maximum : 0;
        }

        private void btBodeSetRPM_Click(object sender, EventArgs e)
        {
            int val = Int32.Parse(chBodeRPM.Text);
            setRPMCmd = new CommandOut(CommandId.CMD_ESC_SET_DEBUG_RPM, (byte)cbESC.SelectedIndex, (byte)(val >> 8), (byte)val);
            setRPMCmd.send();
        }


        int bodeCurrentStep = 0;
        CommandOut bodeLastCommand;

        private void btBodeStart_Click(object sender, EventArgs e)
        {
            bodeCurrentStep = 0;
            sendBodeCommand();
        }

        private Boolean bodeIsEnabled(int channel)
        {
            if (channel == 0) return chBodeEnable1.Checked;
            if (channel == 1) return chBodeEnable2.Checked;
            if (channel == 2) return chBodeEnable3.Checked;
            if (channel == 3) return chBodeEnable4.Checked;
            return false;
        }

        private float bodeGetHzBegin(int channel)
        {
            if (channel == 0) return float.Parse(txtBodeFreqStart1.Text);
            if (channel == 1) return float.Parse(txtBodeFreqStart2.Text);
            if (channel == 2) return float.Parse(txtBodeFreqStart3.Text);
            if (channel == 3) return float.Parse(txtBodeFreqStart4.Text);
            return 0.1f;
        }

        private float bodeGetHzEnd(int channel)
        {
            if (channel == 0) return float.Parse(txtBodeFreqEnd1.Text);
            if (channel == 1) return float.Parse(txtBodeFreqEnd2.Text);
            if (channel == 2) return float.Parse(txtBodeFreqEnd3.Text);
            if (channel == 3) return float.Parse(txtBodeFreqEnd4.Text);
            return 0.2f;
        }

        private float bodeGetHzInc(int channel)
        {
            if (channel == 0) return float.Parse(txtBodeFreqInc1.Text);
            if (channel == 1) return float.Parse(txtBodeFreqInc2.Text);
            if (channel == 2) return float.Parse(txtBodeFreqInc3.Text);
            if (channel == 3) return float.Parse(txtBodeFreqInc4.Text);
            return 0.2f;
        }

        private int bodeGetCycles(int channel)
        {
            if (channel == 0) return Int32.Parse(txtBodeCycles1.Text);
            if (channel == 1) return Int32.Parse(txtBodeCycles2.Text);
            if (channel == 2) return Int32.Parse(txtBodeCycles3.Text);
            if (channel == 3) return Int32.Parse(txtBodeCycles4.Text);
            return 1;
        }

        private int bodeGetAmplitude(int channel)
        {
            if (channel == 0) return Int32.Parse(txtBodeAmplitude1.Text);
            if (channel == 1) return Int32.Parse(txtBodeAmplitude2.Text);
            if (channel == 2) return Int32.Parse(txtBodeAmplitude3.Text);
            if (channel == 3) return Int32.Parse(txtBodeAmplitude4.Text);
            return 1;
        }

        private int bodeEstimateSeconds()
        {
            int ms = 0;
            for (int channel = 0; channel < 4; channel++)
            {
                if (bodeIsEnabled(channel))
                {
                    int steps = (int)Math.Round((bodeGetHzEnd(channel) - bodeGetHzBegin(channel)) / bodeGetHzInc(channel));
                    Console.WriteLine("steps: " + steps + " -- " + bodeGetHzEnd(channel) + " -- " + bodeGetHzBegin(channel) + " -- " + bodeGetHzInc(channel));
                    float freq = bodeGetHzBegin(channel);

                    while (steps > 0)
                    {
                        int duration = (int)((1000.0 * bodeGetCycles(channel)) / (freq));
                        Console.WriteLine(duration);
                        ms += duration;
                        ms += 250;

                        freq += bodeGetHzInc(channel);
                        steps--;
                    }
                }
            }

            return ms / 1000;
        }

        private void bodeResponse(CommandOut cmd)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new cmdOutDelegate(bodeResponse), new object[] { cmd });
                return;
            }

            Console.WriteLine("Bode response: " + cmd.eventResponse);
            if (!cmd.eventResponse) return;

            Console.WriteLine(Tools.getHexString(cmd.responsePacket.packet));
            int freq = Tools.bytesToShort(cmd.responsePacket.packet, 1);

            /*float Re_error = Tools.bytesToFloat(cmd.packet, 3);
            float Im_error = Tools.bytesToFloat(cmd.packet, 7);
            float Re_out = Tools.bytesToFloat(cmd.packet, 11);
            float Im_out = Tools.bytesToFloat(cmd.packet, 15);
            float Re_in = Tools.bytesToFloat(cmd.packet, 19);
            float Im_in = Tools.bytesToFloat(cmd.packet, 23);
            float Re_signal = Tools.bytesToFloat(cmd.packet, 27);
            float Im_signal = Tools.bytesToFloat(cmd.packet, 31);*/

            
            BodeMeasurement b = new BodeMeasurement();
            b.freq = freq / 10.0f;
            b.Error_real = Tools.bytesToRealFloat(cmd.responsePacket.packet, 3);
            b.Error_im = Tools.bytesToRealFloat(cmd.responsePacket.packet, 7);
            b.Out_real = Tools.bytesToRealFloat(cmd.responsePacket.packet, 11);
            b.Out_im = Tools.bytesToRealFloat(cmd.responsePacket.packet, 15);
            b.In_real = Tools.bytesToRealFloat(cmd.responsePacket.packet, 19);
            b.In_im = Tools.bytesToRealFloat(cmd.responsePacket.packet, 23);
            b.Signal_real = Tools.bytesToRealFloat(cmd.responsePacket.packet, 27);
            b.Signal_im = Tools.bytesToRealFloat(cmd.responsePacket.packet, 31);
            bodePlotter.insertMeasurement(b);

            bodeCurrentStep++;
            sendBodeCommand();
        }

        private void sendBodeCommand()
        {
            int bodeCheck = bodeCurrentStep;


            for (int channel = 0; channel < 4; channel++)
            {
                if (!bodeIsEnabled(channel)) continue;
                int steps = (int)Math.Round((bodeGetHzEnd(channel) - bodeGetHzBegin(channel)) / bodeGetHzInc(channel));
                if (bodeCheck < steps)
                {
                    float freq = bodeGetHzBegin(channel) + bodeGetHzInc(channel) * bodeCheck;

                    int amplitude = bodeGetAmplitude(channel);
                    int frequency = (int)(freq * 10.0);
                    int duration = bodeGetCycles(channel);

                    int durationMs = (int)((10000 / frequency) * duration);
                    durationMs += 5000;

                    if (bodeLastCommand != null)
                    {
                        bodeLastCommand.hasCallback = false;
                    }
                    bodeLastCommand = new CommandOut(CommandId.CMD_MOTOR_BODE, (byte)cbESC.SelectedIndex,
                        (byte)(frequency >> 8), (byte)(frequency & 0xFF),
                         (byte)(amplitude >> 8), (byte)(amplitude & 0xFF),
                        (byte)(duration >> 8), (byte)(duration & 0xFF))
                        .callbackOnResponsePacket(CommandId.CMD_MOTOR_BODE, bodeResponse)
                        .setTimeout(durationMs)
                        .send();

                    return;
                }

                bodeCheck -= steps;
            }
        }

        private void chBodeEnable1_CheckedChanged(object sender, EventArgs e)
        {
            int seconds = bodeEstimateSeconds();
            groupBodeSetup.Text = "Ranges (estimated " +  (seconds / 60) + "m" + (seconds % 60) + "s)";
        }

        private void bodePlotter1_Load(object sender, EventArgs e)
        {

        }

        private void chLog_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbESC.SelectedIndex == -1) return;

            new CommandOut(CommandId.CMD_ESC_GET_DEBUG_FEEDBACK, (byte)cbESC.SelectedIndex, (byte)(chManualRPM.Checked ? 1 : 0), (byte)chLog.SelectedIndex)
                .callbackOnResponsePacket(CommandId.CMD_ESC_GET_DEBUG_FEEDBACK, feedbackResponse)
                .send();
        }

        private void lstSettings_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstSettings.SelectedIndex == -1) return;
            String txt = (String)lstSettings.SelectedItem;

            if (txt.LastIndexOf("(") > -1)
                txtSettingsValue.Text = txt.Substring(txt.LastIndexOf("(") + 1, txt.Length - txt.LastIndexOf("(") - 2);

        }


            
    }
}
